from simpledcpp.core.connections.server_connection import HubManager, ConnectInfo
from simpledcpp.core.managers.connection_manager import ConnectionManager
from simpledcpp.core.managers.queue_manager import QueueManager
from simpledcpp.core.events import Events
from simpledcpp.core.settings import Settings
from simpledcpp.core.base import DCPPPart, DCPPEvent, DCPPTCPSocket
from simpledcpp.core.listener import SearchListener, DownloadListener
from simpledcpp.core.filelist.filelist import FileList
from simpledcpp.core.filelist.generator import FileListGenerator
from thread import start_new_thread as just_start_it

import time
import sys
import os
import shutil


class DCPP(DCPPPart):
	""" Main Client Class. """
	def __init__(self):
		""" Initialize main class. Make .settings directory, check filelist, make child classes """
		if not os.path.isdir(os.path.join(os.getenv("HOME"), ".simpledcpp")):
			os.mkdir(os.path.join(os.getenv("HOME"), ".simpledcpp"))
			shutil.copy(
				os.path.join(os.path.dirname(__file__),'../../../res/ext.key'),
				os.path.join(os.getenv("HOME"),".simpledcpp/")
				)
		self.stopped = 0
		self.settings = Settings()
                self.Events = Events(DEBUG = False)
		self.filelist = FileList(self)
		try:
			self.filelist.Load(
					os.path.join(os.getenv("HOME"), ".simpledcpp/files.xml.bz2")
					)
		except:
			pass
		#Check command-line for --folders and --recreate
		for i in sys.argv:
			if i.startswith('--folders:'):
				dirs = i.split(':',1)[1]
				self.settings.set("shared_dirs", dirs)
				self.settings.save()
			if i == '--recreate':
				self.filelist.stop()
				self._recreate()
				print _('Recreated.')
				sys.exit(0)
			if i.startswith("magnet:"):
				# if user wan't open magnet link from browser.
				# create new socket
				socket = DCPPTCPSocket()
				socket.Connect(('127.0.0.1', int(self.settings.get('local_port','12312'))))
				if not socket.ok():
					# simpledcpp not runned
					# generate action
					self._magnet = i
					self.Events.Subscribe("GUI_READY", self.raise_magnet)
				else:
					# simpledcpp already runned
					# send data to her listener
					socket.Send(i)
					socket.Close()
					print "Magnet sended to program." 
					sys.exit(0)

		#Calculating share size from filelist dictionary
		share_size = 0
		for i in self.filelist.filelist:
			share_size = share_size + int(self.filelist.filelist[i][0])
		self.settings.set("infosharesize",share_size.__str__())
		#Create child classes
		self.QueueManager = QueueManager(self)
		self.queue = self.QueueManager.queue
		self.HubManager = HubManager(self)
		self.ConnectionManager = ConnectionManager(self)
		#Starting listeners
		self.SearchListener = SearchListener(self, 
					('0.0.0.0',
					int(self.settings.get('local_port',12312))))
		try:
			self.DownloadListener = DownloadListener(self,
				('0.0.0.0',int(self.settings.get('local_port',12312)))
				)
		except:
			sys.exit(1)

	def raise_magnet(self, event):
		"""
		Function raise OPEN_MAGNET event.
		"""
		if hasattr(self, "_magnet"):
			self.Event(DCPPEvent("OPEN_MAGNET", (self._magnet,)))

	def _recreate(self):
		""" Function start rehashing process and reload filelist
		after rehashing """
		gen = FileListGenerator(self, self.filelist.filelist)
		dirs = self.settings.get('shared_dirs').split(':')
		dirlist = []
		for i in range(0, len(dirs)/2):
			dirlist.append((dirs[i*2], dirs[i*2 + 1]))
		gen.Regenerate(dirlist, os.path.join(os.getenv("HOME"),
					 ".simpledcpp/files.xml"))
		self.filelist.Load(os.path.join(os.getenv("HOME"),
					 ".simpledcpp/files.xml.bz2"))

	def ConnectTo(self, Address):
		""" Function create ConnectInfo object and start
		connect to server ( Address -> (ip,port) )"""
		info = ConnectInfo(
				self.settings.get("nickname", "nickname"),
				self.settings.get("password", ""),
				self.settings.get("infointerest",""),
				self.settings.get("infospeed",""),
				self.settings.get("infoemail",""),
				self.settings.get("infosharesize",""),
				)
		just_start_it(self.HubManager.Connect,(info, Address))
	def DisconnectFrom(self, Address):
		""" Disconnect from Address. Address -> ip """
		self.HubManager.DisconnectFrom(Address)

	def Event(self, Event):
		""" Make event in Events class. """
		self.Events.Event(Event)

	def stop(self):
		""" Stopping non-DCPPPart objects.
		Other objects must stopped self after ON_SYSTEM_SHUTDOWN event. """
		if not self.stopped:
			self.stopped = 1
			self.settings.stop()
			self.QueueManager.stop()
			self.Event(DCPPEvent("ON_SYSTEM_SHUTDOWN",()))
			sys.exit(0)
#		self.DownloadListener.stop()
#		self.SearchListener.stop()
#		self.HubManager.stop()
#		self.QueueManager.stop()
#		self.ConnectionManager.stop()
